/** 
 *  Copyright 2010 Matthew Werny & Burk Price.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package net.iceflow.db.migration.version;

import java.sql.Connection;
import java.util.Date;
import java.util.Set;

import net.iceflow.db.jdbc.DatabaseType;

/**
 * Abstracts all things related to querying about and recording changes to the current state (i.e. version) of the database.
 * <p/>
 * Connections passed into any instance of a <code>VersionStrategy</code> should not be closed under any circumstances.
 * @version 1.0
 * @version 1.1
 */
public interface VersionStrategy {
	/**
	 * DEFAULT_VERSION_TABLE: {@value}
	 * 
	 * @since 1.1
	 */
	public static final String DEFAULT_VERSION_TABLE = "schema_version";

	/**
	 * DEFAULT_VERSION_COLUMN: {@value}
	 * 
	 * @since 1.1
	 */
	public static final String DEFAULT_VERSION_COLUMN = "version";

	/**
	 * DEFAULT_APPLIED_DATE_COLUMN: {@value}
	 * 
	 * @since 1.1
	 */
	public static final String DEFAULT_APPLIED_DATE_COLUMN = "applied_on";

	/**
	 * DEFAULT_DURATION_COLUMN: {@value}
	 * 
	 * @since 1.1
	 */
	public static final String DEFAULT_DURATION_COLUMN = "duration";

	/**
	 * Prepares a virgin database to be versioned using migrations, creating the necessary table(s) and initializing them to the version 0 state.
	 *
	 * @param dbType
	 * @param connection   an open connection to the database (which should not be closed)
	 */
	void enableVersioning(DatabaseType dbType, Connection connection);

	/**
	 * Queries the underlying database and returns a set of all migration version that have already been applied.
	 *
	 * @param dbType
	 * @param connection   an open connection to the database (which should not be closed) @return a set of migration versions that have already been applied;
	 *                     an empty set if none have been applied; null if this database has not yet be enabled for migrations.
	 * @return a set including the versions of all already applied migrations; the name is not included, only the versions.
	 */
	Set<String> appliedMigrations(DatabaseType dbType, Connection connection);

	/**
	 * Captures in the database that the migration to the specified version has happened.
	 *
	 * @param dbType
	 * @param connection   an open connection to the database (which should not be closed)
	 * @param version      the version of the most recently completed migration (i.e. the now-current version of the database)
	 * @param startTime    when the migration was started
	 * @param duration     how long in milliseconds the migration took
	 */
	void recordMigration(DatabaseType dbType, Connection connection, String version, Date startTime, long duration);
}
